package com.sinooceangroup.capital.gateway.filter;

import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.core.Ordered;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StringUtils;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.util.UriComponentsBuilder;
import reactor.core.publisher.Mono;

import java.net.URI;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.UUID;

/**
 * 普通的自定义GatewayFilter
 * 自定义Filter的实现方式有两种：
 * 一、实现 GatewayFilter, Ordered 接口.{@link GatewayFilter}
 *    这种方式的代码处理逻辑和{@link GlobalFilter}的实现逻辑一致 。{@link AuthorizeGlobalFilter}
 *    @Bean
 *    public RouteLocator routeLocator(RouteLocatorBuilder builder) {
 *         return builder.routes().route(r ->
 *                 r.path("/consumer/filter/**")
 *                         .uri("lb://consumer-service:8080")
 *                         .filters(new NormalGatewayFilter())
 *                         .id("consumer-service-route"))
 *                 .build();
 *     }
 * 二、继承 AbstractGatewayFilterFactory 类。{@link AbstractGatewayFilterFactory}
 *
 * @author: Leo.Wang, adwyxx@qq.com
 * @date: 2020/7/23 9:07
 */
public class NormalGatewayFilter implements GatewayFilter, Ordered {
    private final DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        //1.Pre阶段：对Request拦截，并加工
        ServerHttpRequest request = exchange.getRequest();
        //给URL中添加了一个参数NormalGatewayFilterDoPreTime
        ServerHttpRequest newRequest =changeRequest(request);
        //2.Post阶段：在chain.filter(exchange).then()方法中对返回来的Response进行加工
        return chain.filter(exchange.mutate().request(newRequest).build()).then(Mono.fromRunnable(()->{
            //获取返回的Response，并添加一个Http Header
            ServerHttpResponse response = exchange.getResponse();
            response.getHeaders().add("NormalGatewayFilterDoPostTime",  LocalDateTime.now().format(dateTimeFormatter));
        }));
    }

    @Override
    public int getOrder() {
        return 0;
    }

    private ServerHttpRequest changeRequest(ServerHttpRequest request ){
        URI uri = request.getURI();
        StringBuilder query = new StringBuilder();
        String originalQuery = uri.getRawQuery();

        if (StringUtils.hasText(originalQuery)) {
            query.append(originalQuery);
            if (originalQuery.charAt(originalQuery.length() - 1) != '&') {
                query.append('&');
            }
        }

        query.append("time");
        query.append('=');
        query.append(LocalDateTime.now().format(dateTimeFormatter));

        try {
            URI newUri = UriComponentsBuilder.fromUri(uri)
                    .replaceQuery(query.toString())
                    .build(true)
                    .toUri();

           return request.mutate().uri(newUri).build();
        } catch (RuntimeException ex) {
            throw new IllegalStateException("Invalid URI query: \"" + query.toString() + "\"");
        }
    }
}
